<template>
	<baseDialog ref="dialogRef" title="编辑代码生成" width="960px" :isFullscreen="true" @confirm="handleSubmit" @close="handleClose">
		<el-tabs v-model="activeName">
			<el-tab-pane label="基础配置" name="base">
				<el-form ref="baseFormRef" :model="formData" label-width="100px" :rules="baseRules">
					<el-divider content-position="left">基本信息</el-divider>
					<el-row :gutter="35">
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="表名称：" prop="table_name">
								<el-input v-model="formData.table_name" placeholder="请输入表名称" clearable />
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="表描述：" prop="table_comment">
								<el-input v-model="formData.table_comment" placeholder="请输入表描述" clearable />
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="作者：" prop="author">
								<el-input v-model="formData.author" placeholder="请输入作者" clearable />
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="备注：" prop="remark">
								<el-input
									v-model="formData.remark"
									placeholder="请输入备注"
									type="textarea"
									:autosize="{ minRows: 4, maxRows: 2 }"
									show-word-limit
									clearable
								></el-input>
							</el-form-item>
						</el-col>
					</el-row>
					<el-divider content-position="left">生成信息</el-divider>
					<el-row :gutter="35">
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="模块名称：" prop="module_name">
								<el-input v-model="formData.module_name" placeholder="请输入模块名称" clearable />
								<div class="el-form-tips">生成代码所属模块名称，例如：admin</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="类目录：" prop="class_folder">
								<el-input v-model="formData.class_folder" placeholder="请输入类目录" clearable />
								<div class="el-form-tips">控制器/服务类文件所在二级目录名称，例如：test</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="类名称：" prop="class_name">
								<el-input v-model="formData.class_name" placeholder="请输入类名称" clearable />
								<div class="el-form-tips">生成控制器/服务类文件的名称，例如：test</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="模板类型：" prop="tpl_type">
								<el-radio-group v-model="formData.tpl_type">
									<el-radio :label="1">单表</el-radio>
									<el-radio :label="2">树表</el-radio>
								</el-radio-group>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4" v-if="formData.tpl_type == 2">
							<el-form-item label="树主ID：" prop="tree.id">
								<div>
									<el-select v-model="formData.tree.id" placeholder="请选择树主ID" clearable>
										<el-option
											v-for="item in formData.table_column"
											:key="item.id"
											:label="`${item.column_name}：${item.column_comment}`"
											:value="item.column_name"
										/>
									</el-select>
									<div class="el-form-tips">指定树表的主ID，一般为主键</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4" v-if="formData.tpl_type == 2">
							<el-form-item label="树父ID：" prop="tree.pid">
								<div>
									<el-select v-model="formData.tree.pid" placeholder="请选择树父ID" clearable>
										<template #label="{ column_name, column_comment }">
											<span>{{ column_name }}: {{ column_comment }}</span>
										</template>
										<el-option
											v-for="item in formData.table_column"
											:key="item.id"
											:label="`${item.column_name}：${item.column_comment}`"
											:value="item.column_name"
										/>
									</el-select>
									<div class="el-form-tips">指定树表的父ID，例如：pid</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4" v-if="formData.tpl_type == 2">
							<el-form-item label="树名称：" prop="tree.name">
								<div>
									<el-select v-model="formData.tree.name" placeholder="请选择树名称" clearable>
										<template #label="{ column_name, column_comment }">
											<span>{{ column_name }}: {{ column_comment }}</span>
										</template>
										<el-option
											v-for="item in formData.table_column"
											:key="item.id"
											:label="`${item.column_name}：${item.column_comment}`"
											:value="item.column_name"
										/>
									</el-select>
									<div class="el-form-tips">指定树显示的名称字段，例如：name</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="菜单构建：" prop="menu_type">
								<div>
									<el-radio-group v-model="formData.menu.type">
										<el-radio :label="1">自动构建</el-radio>
										<el-radio :label="2">手动添加</el-radio>
									</el-radio-group>
									<div class="el-form-tips">自动构建：自动执行生成菜单sql。手动添加：自行添加菜单</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="父级菜单：" prop="menu.pid">
								<el-cascader
									:options="menuOptions"
									:props="{ checkStrictly: true, emitPath: false, value: 'id', label: 'name' }"
									placeholder="请选择父级菜单"
									clearable
									v-model="formData.menu.pid"
								>
									<template #default="{ node, data }">
										<span>{{ data.name }}</span>
										<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
									</template>
								</el-cascader>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="菜单名称：" prop="menu.name">
								<el-input v-model="formData.menu.name" placeholder="请输入菜单名称" clearable></el-input>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="删除类型：" prop="delete.type">
								<el-radio-group v-model="formData.delete.type">
									<el-radio :label="0">物理删除</el-radio>
									<el-radio :label="1">软删除</el-radio>
								</el-radio-group>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4" v-if="formData.delete.type == 1">
							<el-form-item label="删除字段：" prop="delete.name">
								<div>
									<el-select v-model="formData.delete.name" placeholder="请选择删除字段" clearable>
										<el-option
											v-for="item in formData.table_column"
											:key="item.id"
											:label="`${item.column_name}：${item.column_comment}`"
											:value="item.column_name"
										/>
									</el-select>
									<div class="el-form-tips">软删除字段，例如：delete_time</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="组件样式：" prop="component_type">
								<el-radio-group v-model="formData.component_type">
									<el-radio :label="1">模态框</el-radio>
									<el-radio :label="2">新页面</el-radio>
									<el-radio :label="3">抽屉</el-radio>
								</el-radio-group>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="生成方式：" prop="crud_type">
								<el-radio-group v-model="formData.crud_type">
									<el-radio :label="1">压缩包下载</el-radio>
									<el-radio :label="2">生成到模块</el-radio>
								</el-radio-group>
							</el-form-item>
						</el-col>
					</el-row>
				</el-form>
			</el-tab-pane>
			<el-tab-pane label="字段配置" name="column">
				<el-card class="!border-none mb-4" shadow="never">
					<el-alert type="warning" :closable="false" show-icon>
						<div>字典类型在显示类型为下拉框、单选框和复选框时才可选择</div>
						<div>扩展设置中设置数据和字典类型只能设置一种</div>
					</el-alert>
				</el-card>
				<el-table ref="columnTableRef" :data="formData.table_column">
					<el-table-column label="字段名称" prop="column_name" min-width="100" />
					<el-table-column label="字段描述" prop="column_comment" min-width="120">
						<template v-slot="{ row }">
							<el-input v-model="row.column_comment" clearable />
						</template>
					</el-table-column>
					<el-table-column label="物理类型" prop="column_type" />
					<el-table-column width="80">
						<template #header>
							<el-checkbox v-model="check_types.is_required" @change="handleCheckbox($event, 'is_required')"><span>必填</span></el-checkbox> 
						</template>
						<template v-slot="{ row }">
							<el-checkbox v-model="row.is_required" :true-label="1" :false-label="0" />
						</template>
					</el-table-column>
					<el-table-column width="80">
						<template #header>
							<el-checkbox v-model="check_types.is_insert" @change="handleCheckbox($event, 'is_insert')"><span>添加</span></el-checkbox> 
						</template>
						<template v-slot="{ row }">
							<el-checkbox v-model="row.is_insert" :true-label="1" :false-label="0" />
						</template>
					</el-table-column>
					<el-table-column width="80">
						<template #header>
							<el-checkbox v-model="check_types.is_update" @change="handleCheckbox($event, 'is_update')"><span>编辑</span></el-checkbox> 
						</template>
						<template v-slot="{ row }">
							<el-checkbox v-model="row.is_update" :true-label="1" :false-label="0" />
						</template>
					</el-table-column>
					<el-table-column width="80">
						<template #header>
							<el-checkbox v-model="check_types.is_list" @change="handleCheckbox($event, 'is_list')"><span>列表</span></el-checkbox> 
						</template>
						<template v-slot="{ row }">
							<el-checkbox v-model="row.is_list" :true-label="1" :false-label="0" />
						</template>
					</el-table-column>
					<el-table-column width="80">
						<template #header>
							<el-checkbox v-model="check_types.is_query" @change="handleCheckbox($event, 'is_query')"><span>查询</span></el-checkbox> 
						</template>
						<template v-slot="{ row }">
							<el-checkbox v-model="row.is_query" :true-label="1" :false-label="0" />
						</template>
					</el-table-column>
					<el-table-column width="80">
						<template #header>
							<el-checkbox v-model="check_types.is_detail" @change="handleCheckbox($event, 'is_detail')"><span>详情</span></el-checkbox> 
						</template>
						<template v-slot="{ row }">
							<el-checkbox v-model="row.is_detail" :true-label="1" :false-label="0" />
						</template>
					</el-table-column>
					<el-table-column label="查询方式">
						<template v-slot="{ row }">
							<el-select v-model="row.query_type">
								<el-option label="=" value="=" />
								<el-option label="!=" value="<>" />
								<el-option label=">" value=">" />
								<el-option label=">=" value=">=" />
								<el-option label="<" value="<" />
								<el-option label="<=" value="<=" />
								<el-option label="IN" value="in" />
								<el-option label="LIKE" value="like" />
								<el-option label="BETWEEN" value="between" />
							</el-select>
						</template>
					</el-table-column>
					<el-table-column label="显示类型" min-width="100">
						<template v-slot="{ row }">
							<el-select v-model="row.view_type">
								<el-option label="输入框" value="input" />
								<el-option label="文本域" value="textarea" />
								<el-option label="数字输入框" value="number" />
								<el-option label="下拉框" value="select" />
								<el-option label="单选框" value="radio" />
								<el-option label="复选框" value="checkbox" />
								<el-option label="日期选择器" value="datePicker" />
								<el-option label="时间选择器" value="timePicker" />
								<el-option label="图片选择器" value="imageSelect" />
								<el-option label="视频选择器" value="videoSelect" />
								<el-option label="文件选择器" value="fileSelect" />
								<el-option label="用户信息选择器" value="userSelect" />
								<el-option label="省市区选择器" value="areaSelect" />
								<el-option label="富文本编辑器" value="editor" />
							</el-select>
						</template>
					</el-table-column>
					<el-table-column label="扩展设置" min-width="80" align="center">
						<template v-slot="{ $index, row }">
							<el-button
								type="primary"
								class="w-2"
								:disabled="!view_types.hasOwnProperty(row.view_type) || Number(row.dict_type) > 0"
								@click="openViewDialog($index, row)"
								><SvgIcon name="ele-Setting" size="12" class="!mr-0"
							/></el-button>
						</template>
					</el-table-column>
					<el-table-column label="字典类型" min-width="120">
						<template v-slot="{ $index, row }">
							<el-select
								v-model="row.dict_type"
								clearable
								:disabled="
									!(row.view_type == 'select' || row.view_type == 'radio' || row.view_type == 'checkbox') ||
									(row.extra?.list && row.extra?.list.length)
								"
								placeholder="请选择字典类型"
								@change="dictTypeChange($event, $index)"
							>
								<el-option v-for="(item, index) in dictDataList" :key="index" :label="item.name" :value="String(item.id)" :disabled="!item.status" />
							</el-select>
						</template>
					</el-table-column>
				</el-table>
				<el-dialog v-model="viewTypeData.dialog" :title="viewTypeData.title" width="750">
					<el-form ref="viewFormRef" :model="viewSelectData" label-width="100px">
						<div v-if="viewTypeData.type == 'input'">
							<el-form-item label="是否加密：" prop="input.is_password">
								<el-radio-group v-model="viewSelectData.input.is_password">
									<el-radio :label="false">否</el-radio>
									<el-radio :label="true">是</el-radio>
								</el-radio-group>
							</el-form-item>
						</div>
						<div v-if="viewTypeData.type == 'number'">
							<el-form-item label="最小值：" prop="number.min">
								<div class="w-80">
									<el-input-number v-model="viewSelectData.number.min" placeholder="请输入最小值" clearable />
								</div>
							</el-form-item>
							<el-form-item label="最小值：" prop="number.max">
								<div class="w-80">
									<el-input-number v-model="viewSelectData.number.max" placeholder="请输入最大值" clearable />
								</div>
							</el-form-item>
						</div>
						<div v-if="viewTypeData.type == 'checkbox'">
							<el-form-item label="设置数据：" prop="checkbox.list">
								<formTable ref="table" v-model="viewSelectData.checkbox.list" :template="{ name: '', value: '' }" drag-sort placeholder="暂无数据">
									<el-table-column prop="name" label="名称" min-width="180">
										<template #default="scope">
											<el-input v-model="scope.row.name" placeholder="请输入名称"></el-input>
										</template>
									</el-table-column>
									<el-table-column prop="value" label="值" min-width="180">
										<template #default="scope">
											<el-input v-model="scope.row.value" placeholder="请输入值"></el-input>
										</template>
									</el-table-column>
								</formTable>
							</el-form-item>
						</div>
						<div v-if="viewTypeData.type == 'radio'">
							<el-form-item label="设置数据：" prop="radio.list">
								<formTable ref="table" v-model="viewSelectData.radio.list" :template="{ name: '', value: '' }" drag-sort placeholder="暂无数据">
									<el-table-column prop="name" label="名称" min-width="180">
										<template #default="scope">
											<el-input v-model="scope.row.name" placeholder="请输入名称"></el-input>
										</template>
									</el-table-column>
									<el-table-column prop="value" label="值" min-width="180">
										<template #default="scope">
											<el-input v-model="scope.row.value" placeholder="请输入值"></el-input>
										</template>
									</el-table-column>
								</formTable>
							</el-form-item>
						</div>
						<div v-if="viewTypeData.type == 'select'">
							<el-form-item label="是否多选：" prop="select.multiple">
								<el-radio-group v-model="viewSelectData.select.multiple">
									<el-radio :label="false">否</el-radio>
									<el-radio :label="true">是</el-radio>
								</el-radio-group>
							</el-form-item>
							<el-form-item label="设置数据：" prop="select.list">
								<formTable ref="table" v-model="viewSelectData.select.list" :template="{ name: '', value: '' }" drag-sort placeholder="暂无数据">
									<el-table-column prop="name" label="名称" min-width="180">
										<template #default="scope">
											<el-input v-model="scope.row.name" placeholder="请输入名称"></el-input>
										</template>
									</el-table-column>
									<el-table-column prop="value" label="值" min-width="180">
										<template #default="scope">
											<el-input v-model="scope.row.value" placeholder="请输入值"></el-input>
										</template>
									</el-table-column>
								</formTable>
							</el-form-item>
						</div>
						<div v-if="viewTypeData.type == 'imageSelect'">
							<el-form-item label="是否弹框：" prop="imageSelect.is_dialog">
								<el-radio-group v-model="viewSelectData.imageSelect.is_dialog">
									<el-radio :label="true">是</el-radio>
									<el-radio :label="false">否</el-radio>
								</el-radio-group>
							</el-form-item>
							<el-form-item label="上传数量：" prop="imageSelect.limit_count">
								<div class="w-80">
									<el-input-number v-model="viewSelectData.imageSelect.limit_count" placeholder="请输入上传数量" clearable />
								</div>
							</el-form-item>
						</div>
						<div v-if="viewTypeData.type == 'fileSelect'">
							<el-form-item label="是否弹框：" prop="fileSelect.is_dialog">
								<el-radio-group v-model="viewSelectData.fileSelect.is_dialog">
									<el-radio :label="true">是</el-radio>
									<el-radio :label="false">否</el-radio>
								</el-radio-group>
							</el-form-item>
							<el-form-item label="上传数量：" prop="fileSelect.limit_count">
								<div class="w-80">
									<el-input-number v-model="viewSelectData.fileSelect.limit_count" placeholder="请输入上传数量" clearable />
								</div>
							</el-form-item>
						</div>
						<div v-if="viewTypeData.type == 'videoSelect'">
							<el-form-item label="是否弹框：" prop="videoSelect.is_dialog">
								<el-radio-group v-model="viewSelectData.videoSelect.is_dialog">
									<el-radio :label="true">是</el-radio>
									<el-radio :label="false">否</el-radio>
								</el-radio-group>
							</el-form-item>
							<el-form-item label="上传数量：" prop="videoSelect.limit_count">
								<div class="w-80">
									<el-input-number v-model="viewSelectData.videoSelect.limit_count" placeholder="请输入上传数量" clearable />
								</div>
							</el-form-item>
						</div>
						<div v-if="viewTypeData.type == 'userSelect'">
							<el-form-item label="是否多选：" prop="userSelect.multiple">
								<el-radio-group v-model="viewSelectData.userSelect.multiple">
									<el-radio :label="false">否</el-radio>
									<el-radio :label="true">是</el-radio>
								</el-radio-group>
							</el-form-item>
							<el-form-item label="用户数量：" prop="userSelect.limit_count" v-if="viewSelectData.userSelect.multiple">
								<div class="w-80">
									<el-input-number v-model="viewSelectData.userSelect.limit_count" placeholder="请输入用户数量" clearable />
								</div>
							</el-form-item>
						</div>
					</el-form>
					<template #footer>
						<div class="dialog-footer">
							<el-button @click="viewTypeData.dialog = false">取消</el-button>
							<el-button type="primary" @click="confimViewForm()"> 确认 </el-button>
						</div>
					</template>
				</el-dialog>
			</el-tab-pane>
			<el-tab-pane label="功能配置" name="sys">
				<el-card class="!border-none mb-4" shadow="never">
					<el-alert type="warning" :closable="false" show-icon>
						<div>未勾选功能，不生成对应按钮、菜单、接口及文件</div>
						<div>列表功能是默认的，直接生成</div>
					</el-alert>
				</el-card>
				<el-form ref="sysFormRef" :model="formData" label-width="100px">
					<el-divider content-position="left">功能列表</el-divider>
					<el-row :gutter="35">
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="添加：" prop="is_insert">
								<div>
									<el-switch v-model="formData.is_insert" :active-value="1" :inactive-value="0" />
									<div class="el-form-tips">勾选生成添加数据按钮、菜单、接口及文件</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="编辑：" prop="is_update">
								<div>
									<el-switch v-model="formData.is_update" :active-value="1" :inactive-value="0" />
									<div class="el-form-tips">勾选生成编辑数据按钮、菜单、接口及文件</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="删除：" prop="is_delete">
								<div>
									<el-switch v-model="formData.is_delete" :active-value="1" :inactive-value="0" />
									<div class="el-form-tips">勾选生成删除数据按钮、菜单、接口及文件</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="详情：" prop="is_detail">
								<div>
									<el-switch v-model="formData.is_detail" :active-value="1" :inactive-value="0" />
									<div class="el-form-tips">勾选生成数据详情按钮、菜单、接口及文件</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="导出：" prop="is_export">
								<div>
									<el-switch v-model="formData.is_export" :active-value="1" :inactive-value="0" />
									<div class="el-form-tips">勾选生成导出数据按钮、菜单、接口及文件</div>
								</div>
							</el-form-item>
						</el-col>
						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-4">
							<el-form-item label="导入：" prop="is_import">
								<div>
									<el-switch v-model="formData.is_import" :active-value="1" :inactive-value="0" />
									<div class="el-form-tips">勾选生成导入数据按钮、菜单、接口及文件</div>
								</div>
							</el-form-item>
						</el-col>
					</el-row>
				</el-form>
				<el-divider content-position="left">生成文件路径</el-divider>
				<el-row :gutter="35">
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2">
						后端控制器文件：
						<el-link type="primary"
							>app/{{ formData.module_name }}/controller{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{
								toStudly(formData.class_name)
							}}.php</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2">
						后端服务类文件：
						<el-link type="primary"
							>app/{{ formData.module_name }}/service{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{
								toStudly(formData.class_name)
							}}Service.php</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2">
						后端验证器文件：
						<el-link type="primary"
							>app/{{ formData.module_name }}/validate{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{
								toStudly(formData.class_name)
							}}Validate.php</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2">
						后端数据库模型文件：
						<el-link type="primary"
							>app/common/model{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{
								toStudly(formData.table_name.slice(formData.table_prefix.length))
							}}.php</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2">
						后端路由文件：
						<el-link type="primary"
							>app/{{ formData.module_name }}/route{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{
								toStudly(formData.class_name, false)
							}}.php</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2">
						前端接口文件：
						<el-link type="primary"
							>src/api{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{ toStudly(formData.class_name, false) }}.ts</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2">
						前端列表页面文件：
						<el-link type="primary"
							>src/views{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{ toStudly(formData.class_name, false) }}/index.vue</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2" v-if="formData.is_insert || formData.is_update">
						前端编辑页面文件：
						<el-link type="primary"
							>src/views{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{
								toStudly(formData.class_name, false)
							}}/component/edit.vue</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2" v-if="formData.is_detail">
						前端详情页面文件：
						<el-link type="primary"
							>src/views{{ formData.class_folder ? '/' + formData.class_folder : '' }}/{{
								toStudly(formData.class_name, false)
							}}/component/detail.vue</el-link
						>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb-2 mt-2" v-if="formData.is_import">
						导入excel示例文件：
						<el-link type="primary">uploads/excel/{{ formData.table_comment }}导入示例.xlsx</el-link>
					</el-col>
				</el-row>
			</el-tab-pane>
			<el-tab-pane label="关联配置" name="join">
				<el-form :model="formData" :rules="joinRules" class="join-form" ref="joinFormRef">
					<formTable
						ref="joinTableRef"
						v-model="formData.join"
						:template="{ type: '', name: '', model: '', foreign_key: '', primary_key: '' }"
						drag-sort
						placeholder="暂无数据"
					>
						<el-table-column prop="type" label="关联类型" min-width="180">
							<template #default="scope">
								<el-form-item :prop="`join[${scope.$index}].type`" :rules="joinRules.type">
									<div>
										<el-select v-model="scope.row.type" placeholder="请选择关联类型" class="w-full" clearable>
											<el-option label="1对1" value="hasOne" />
											<el-option label="1对多" value="hasMany" />
										</el-select>
										<div class="el-form-tips">选择关联类型</div>
									</div>
								</el-form-item>
							</template>
						</el-table-column>
						<el-table-column prop="name" label="关联名称" min-width="180">
							<template #default="scope">
								<el-form-item :prop="`join[${scope.$index}].name`" :rules="joinRules.name">
									<el-input v-model="scope.row.name" placeholder="请输入关联名称"></el-input>
									<div class="el-form-tips">代码关联模型命名</div>
								</el-form-item>
							</template>
						</el-table-column>
						<el-table-column prop="model" label="关联模型" min-width="180">
							<template #default="scope">
								<el-form-item :prop="`join[${scope.$index}].model`" :rules="joinRules.model">
									<div>
										<el-select v-model="scope.row.model" placeholder="请选择关联模型" class="w-full" clearable>
											<el-option v-for="item in modelDataList" :key="item" :label="item" :value="item" />
										</el-select>
										<div class="el-form-tips">关联表的模型文件</div>
									</div>
								</el-form-item>
							</template>
						</el-table-column>
						<el-table-column prop="primary_key" label="关联键" min-width="180">
							<template #default="scope">
								<el-form-item :prop="`join[${scope.$index}].primary_key`" :rules="joinRules.primary_key">
									<div>
										<el-select v-model="scope.row.primary_key" placeholder="请选择关联键" class="w-full" clearable>
											<el-option
												v-for="item in formData.table_column"
												:key="item.id"
												:label="`${item.column_name}：${item.column_comment}`"
												:value="item.column_name"
											/>
										</el-select>
										<div class="el-form-tips">本表的外键</div>
									</div>
								</el-form-item>
							</template>
						</el-table-column>
						<el-table-column prop="foreign_key" label="外键" min-width="180">
							<template #default="scope">
								<el-form-item :prop="`join[${scope.$index}].foreign_key`" :rules="joinRules.foreign_key">
									<el-input v-model="scope.row.foreign_key" placeholder="请输入外键"></el-input>
									<div class="el-form-tips">关联表的外键</div>
								</el-form-item>
							</template>
						</el-table-column>
					</formTable>
				</el-form>
			</el-tab-pane>
		</el-tabs>
	</baseDialog>
</template>

<script setup lang="ts" name="codeEdit">
import { ref, shallowRef, reactive, onMounted } from 'vue';
import type { FormInstance } from 'element-plus';
import { messageError, messageSuccess } from '/@/utils/message';
import { toStudly } from '/@/utils/util';
import { menuLists } from '/@/api/auth/menu';
import { getCrudTypeList, getModelList } from '/@/api/crud/table';
import { codeDetail, codeEdit } from '/@/api/crud/code';

const dialogRef = ref(null);

const baseFormRef = shallowRef<FormInstance>();

const sysFormRef = shallowRef<FormInstance>();

const joinFormRef = shallowRef<FormInstance>();

const viewFormRef = shallowRef<FormInstance>();

const columnTableRef = ref(null);

const joinTableRef = ref(null);

const activeName = ref('base');

const emit = defineEmits(['submit', 'close']);

// 表单数据
const formData = reactive({
	id: 0,
	// base
	table_name: '',
	table_comment: '',
	table_prefix: '',
	author: '',
	remark: '',
	module_name: '',
	class_folder: '',
	class_name: '',
	tpl_type: 1,
	crud_type: 1,
	component_type: 1,
	menu: {
		pid: 0,
		type: 1,
		name: '',
	},
	delete: {
		type: 0,
		name: '',
	},
	tree: {
		id: '',
		pid: '',
		name: '',
	},
	// column
	table_column: [],
	// sys
	is_insert: 1,
	is_update: 1,
	is_delete: 1,
	is_detail: 0,
	is_export: 0,
	is_import: 0,
	// join
	join: [],
});

// 扩展数据
const viewTypeData = reactive({
	index: 0,
	title: '',
	dialog: false,
	type: '',
});

const viewSelectData = reactive({
	input: {
		is_password: false,
	},
	number: {
		min: 0,
		max: 99999,
	},
	checkbox: {
		list: [],
	},
	radio: {
		list: [],
	},
	select: {
		multiple: false,
		list: [],
	},
	imageSelect: {
		is_dialog: true,
		limit_count: 1,
	},
	fileSelect: {
		is_dialog: true,
		limit_count: 1,
	},
	videoSelect: {
		is_dialog: true,
		limit_count: 1,
	},
	userSelect: {
		multiple: false,
		limit_count: 1,
	},
});

// 数据字典列表
const dictDataList = ref([]);

const getDictList = async () => {
	dictDataList.value = await getCrudTypeList();
};

// 模型数据列表
const modelDataList = ref([]);

const getModelDataList = async () => {
	modelDataList.value = await getModelList();
};

// 上级菜单列表
const menuOptions = ref([]);

const getMenuData = async () => {
	menuOptions.value = await menuLists({ type: ['M', 'C'] });
};

// 基础验证
const baseRules = reactive({
	table_name: [{ required: true, message: '请输入表名称', trigger: ['blur'] }],
	table_comment: [{ required: true, message: '请输入表描述', trigger: ['blur'] }],
	module_name: [{ required: true, message: '请输入模块名称', trigger: ['blur'] }],
	class_name: [{ required: true, message: '请输入类名称', trigger: ['blur'] }],
	'tree.id': [{ required: true, message: '请选择树主ID', trigger: ['change'] }],
	'tree.pid': [{ required: true, message: '请选择树父ID', trigger: ['change'] }],
	'tree.name': [{ required: true, message: '请选择树名称', trigger: ['blur'] }],
	'menu.pid': [{ required: true, message: '请选择父级菜单', trigger: ['change'] }],
	'menu.name': [{ required: true, message: '请输入菜单名称', trigger: ['blur'] }],
});

// 关联验证
const joinRules = reactive({
	type: [{ required: true, message: '请选择关联类型', trigger: ['change'] }],
	name: [{ required: true, message: '请输入关联名称', trigger: ['blur'] }],
	model: [{ required: true, message: '请选择关联模型', trigger: ['change'] }],
	foreign_key: [{ required: true, message: '请输入外键', trigger: ['blur'] }],
	primary_key: [{ required: true, message: '请选择关联键', trigger: ['change'] }],
});

// 扩展设置控件
const view_types = {
	input: '输入框',
	number: '数字输入框',
	select: '下拉框',
	checkbox: '复选框',
	radio: '单选框',
	imageSelect: '图片选择器',
	videoSelect: '视频选择器',
	fileSelect: '文件选择器',
	userSelect: '用户信息选择器',
};

// 选中控制控件
const check_types = reactive({
	is_required: false,
	is_insert: false,
	is_update: false,
	is_list: false,
	is_query: false,
	is_detail: false,
});

const dictTypeChange = (value: any, index) => {
	// 选择字典类型时清空设置数据
	if (value) formData.table_column[index].extra = '';
};

const handleCheckbox = (val: any, type: any) => {
	for (let i = 0; i < formData.table_column.length; i++) {
		formData.table_column[i][type] = (val?1:0);
	}
}

const openViewDialog = async (index: number, row: any) => {
	viewTypeData.index = index;
	viewTypeData.title = '设置' + view_types[row.view_type] + ' - ' + row.column_comment;
	viewTypeData.type = row.view_type;
	// 数据赋值
	for (const key in viewSelectData[row.view_type]) {
		if (row.extra[key] != null && row.extra[key] != undefined) {
			viewSelectData[row.view_type][key] = row.extra[key];
		}
	}

	// 初始化
	if (!row.extra) {
		switch (row.view_type) {
			case 'input':
				viewSelectData.input.is_password = false;
				break;
			case 'number':
				viewSelectData.number.min = 0;
				viewSelectData.number.max = 99999;
				break;
			case 'checkbox':
				viewSelectData.checkbox.list = [];
				break;
			case 'radio':
				viewSelectData.radio.list = [];
				break;
			case 'select':
				viewSelectData.select.multiple = false;
				viewSelectData.select.list = [];
				break;
			case 'imageSelect':
				viewSelectData.imageSelect.is_dialog = true;
				viewSelectData.imageSelect.limit_count = 1;
				break;
			case 'fileSelect':
				viewSelectData.fileSelect.is_dialog = true;
				viewSelectData.fileSelect.limit_count = 1;
				break;
			case 'videoSelect':
				viewSelectData.videoSelect.is_dialog = true;
				viewSelectData.videoSelect.limit_count = 1;
				break;
			case 'userSelect':
				viewSelectData.userSelect.multiple = false;
				viewSelectData.userSelect.limit_count = 1;
				break;
			default:
				break;
		}
	}

	viewTypeData.dialog = true;
};

const confimViewForm = () => {
	formData.table_column[viewTypeData.index].extra = JSON.parse(JSON.stringify(viewSelectData[viewTypeData.type]));

	// 设置数据时清空字典类型
	if (viewSelectData[viewTypeData.type]?.list && viewSelectData[viewTypeData.type]?.list.length > 0) {
		formData.table_column[viewTypeData.index].dict_type = '';
	}

	viewTypeData.dialog = false;
};

const setFormData = async (row: any, callback: any) => {
	const data = await codeDetail({
		id: row.id,
	});

	for (const key in formData) {
		if (data[key] != null && data[key] != undefined) {
			formData[key] = data[key];
		}
	}
	callback();
};

const handleSubmit = async () => {
	await baseFormRef.value?.validate(async (baseValid: boolean) => {
		if (!baseValid) {
			messageError('基础配置校验失败');
			return;
		}

		if (formData.join && formData.join.length > 0) {
			await joinFormRef.value?.validate(async (joinValid: boolean) => {
				if (!joinValid) {
					messageError('关联配置校验失败');
					return;
				}
				handleSuccess();
			});
		} else {
			handleSuccess();
		}
	});
};

const handleSuccess = async () => {
	await codeEdit(formData);
	messageSuccess('编辑成功');
	dialogRef.value?.close();
	emit('submit');
};

const handleClose = () => {
	emit('close');
};

const open = () => {
	dialogRef.value?.open();
};

defineExpose({
	open,
	setFormData,
});

onMounted(() => {
	getMenuData();
	getDictList();
	getModelDataList();
});
</script>
<style lang="scss" scoped>
.join-form.el-form .el-form-item:last-of-type {
	margin-bottom: 15px !important;
	margin-top: 15px !important;
}
</style>
